package com.rohoo.framework.struts.action;

import java.io.Serializable;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.DynaProperty;

import com.rohoo.framework.util.DateUtil;
import com.rohoo.framework.util.StringUtil;

public class ParamsTable implements Serializable {
	
	private HashMap params = new HashMap();

	private ServletContext context;

	private String siteHttp;
 
	private String contextPath;
	
	private String requestURL ;
	
	private HttpServletRequest request;

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	/**
	 * Set the parameter.
	 * 
	 * @param name
	 *            The parameter name.
	 * @param value
	 *            The parameter value.
	 */
	public void setParameter(String name, Object value) {
		if (value instanceof String) {
			params.put(name, StringUtil.dencodeHTML((String) value));
		} else {
			params.put(name, value);
		}
	}

	/**
	 * Get the parameter
	 * 
	 * @param name
	 *            The parameter name.
	 * @return The parameter value.
	 */
	public Object getParameter(String name) {
		return params.get(name);
	}

	/**
	 * Get the parameter in string format.
	 * 
	 * @param name
	 *            The parameter name.
	 * @return The parameter value in string value.
	 */
	public String getParameterAsString(String name) {
		Object obj = params.get(name);

		if (obj instanceof String)
			return (String) obj;
		else if (obj instanceof String[])
			return StringUtil.unite((String[]) obj);
		else
			return (obj != null) ? obj.toString() : null;
	}

	/**
	 * Get the parameter in text format.
	 * 
	 * @param name
	 *            The parameter name.
	 * @return The parameter value in text value.
	 */
	public String getParameterAsText(String name) {
		Object obj = params.get(name);

		if (obj instanceof String)
			return (String) obj;
		else if (obj instanceof String[])
			return StringUtil.unite((String[]) obj);
		else
			return (obj != null) ? obj.toString() : null;
	}

	/**
	 * Get the parameter in double format.
	 * 
	 * @param name
	 *            The parameter name.
	 * @return The parameter value in double value.
	 */
	public Double getParameterAsDouble(String name) {
		Object obj = params.get(name);
		if (obj instanceof String) {
			String value = (String) obj;

			try {
				return Double.valueOf(value);
			} catch (Exception e) {
				return new Double(0.0);
			}
		}

		return null;
	}

	/**
	 * Get the parameter in long format.
	 * 
	 * @param name
	 *            The parameter name.
	 * @return The parameter value in long value.
	 */
	public Long getParameterAsLong(String name) {
		Object obj = params.get(name);

		if (obj instanceof String) {
			String value = (String) obj;
			try {
				return Long.valueOf(value);
			} catch (Exception e) {
				return new Long(0);
			}
		}

		return null;
	}

	/**
	 * Get the parameter in date format.
	 * 
	 * @param name
	 *            The parameter name.
	 * @return The parameter value in date value.
	 */
	public Date getParameterAsDate(String name) {
		Object obj = params.get(name);
		if (obj instanceof String) {
			try {
				String value = (String) obj;
				if (value != null && StringUtil.isDate(value))
					return new Date(DateUtil.parseDate(value).getTime());
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}

	/**
	 * Return the parameter names
	 * 
	 * @return The parameter names.
	 */
	public Iterator getParameterNames() {
		return params.keySet().iterator();
	}

	/**
	 * Retrieve the paramters from the http request.
	 * 
	 * @param request
	 *            The http request.
	 * @return The paramters tables.
	 */
	public static ParamsTable convertHTTP(HttpServletRequest request) {
		ParamsTable params = new ParamsTable();

		params.context = request.getSession().getServletContext();
		params.siteHttp = request.getServerName();
		params.contextPath = request.getContextPath();
		params.requestURL = request.getRequestURL().toString();
		params.request = request;
		

		Enumeration en = request.getParameterNames();
		if (en != null) {
			while (en.hasMoreElements()) {
				String name = (String) en.nextElement();

				String[] list = request.getParameterValues(name);
				if (list != null && list.length > 1) {
					params.setParameter(name, list);
				} else {
					params.setParameter(name, request.getParameter(name));
				}
			}
		}

		return params;
	}

	/**
	 * Get the parameter value in arrary.
	 * 
	 * @param name
	 *            The parameter name.
	 * @param index
	 *            The parameter index in arrary
	 * @return The parameter value
	 */
	public Object getParameter(String name, int index) {
		Object obj = params.get(name);
		if (obj != null && obj instanceof java.lang.reflect.Array) {
			String[] col = (String[]) obj;

			return col[index];
		}
		return null;
	}

	/**
	 * Set a parameter in arrary.
	 * 
	 * @param name
	 *            The parameter name.
	 * @param index
	 *            The parameter index in arrary.
	 * @param value
	 *            The parameter value.
	 */
	public void setParameter(String name, int index, Object value) {
		Object obj = params.get(name);
		if (obj != null && obj instanceof String[]) {
			String[] col = (String[]) obj;
			col[index] = (String) value;
		}
	}

	/**
	 * Get The dynamic properties from the parameters.
	 * 
	 * @return The dynamic properties.
	 */
	public DynaProperty[] getDynaProperties() {
		DynaProperty[] dynaProps = new DynaProperty[params.size()];
		Iterator iter = params.keySet().iterator();
		int count = 0;

		while (iter.hasNext()) {
			String paramName = (String) iter.next();
			DynaProperty prop = new DynaProperty(paramName, params.get(
					paramName).getClass());
			dynaProps[count] = prop;
			count++;
		}
		return dynaProps;
	}

	/**
	 * Get the dynamic property from the parameters.
	 * 
	 * @param name
	 *            The parameter mame.
	 * @return he dynamic property
	 */
	public DynaProperty getDynaProperty(String name) {
		DynaProperty prop = null;

		if (params.get(name) != null)
			prop = new DynaProperty(name, params.get(name).getClass());
		else
			prop = new DynaProperty(name, String.class);

		return prop;
	}

	/**
	 * Remove the parameter
	 * 
	 * @param name
	 *            The parameter name
	 */
	public void removeParameter(String name) {
		params.remove(name);
	}

	/**
	 * Get the the http site name.
	 * 
	 * @return The http site name.
	 */
	public String getSiteHttp() {
		return siteHttp;
	}

	public String getContextPath() {
		if (this.contextPath != null) {
			return this.contextPath;
		}
		return "/";

	}
	
	public String getRequestURL(){
		return requestURL;
	}
	public void setRequestURL(String requestURL){
		this.requestURL = requestURL;
	}

	public void setContextPath(String contextPath) {
		this.contextPath = contextPath;
	}

	public void putAll(Map map) {
		this.params.putAll(map);
	}

	public boolean equals(Object obj) {
		if (obj != null) {
			ParamsTable pt = (ParamsTable) obj;
			return this.params.equals(pt.params);
		}
		return false;
	}
}
